package com.gitee.wsl.common.ui.draw.style

import androidx.compose.ui.graphics.drawscope.DrawStyle
import androidx.compose.ui.graphics.drawscope.Fill
import androidx.compose.ui.graphics.drawscope.Stroke
import com.gitee.wsl.common.ui.base.ColorOrBrush
import com.gitee.wsl.common.ui.draw.type.TextHAlign
import com.gitee.wsl.common.ui.draw.type.TextVAlign
import com.gitee.wsl.ext.any.ifNullValue

/**
 * Holds the styling property.
 */
 interface NodeStyle {

    var fill: ColorOrBrush?

    var strokeColor: ColorOrBrush?
    var strokeWidth: Float?
    var textColor: ColorOrBrush?

    /**
     * The dashedLine can be set to null or to an array of a minimal size of 2.
     */
     var dashedLine: DoubleArray?

     var hAlign: TextHAlign

     var vAlign: TextVAlign

     companion object
}

internal class NodeStyleImpl: NodeStyle {
    override var fill: ColorOrBrush? = null

    override var strokeColor: ColorOrBrush? = null

    override var dashedLine: DoubleArray? = null
        get() = field
        set(value) {
            require( value == null || (value.size > 1) )
            { "The dashedLine can be set to null or to an array of a minimal size of 2." }
            field = value
        }

    override var textColor: ColorOrBrush? = null
    override var strokeWidth: Float? = 1.0f
    override var hAlign: TextHAlign = TextHAlign.LEFT

    override var vAlign: TextVAlign = TextVAlign.BASELINE

}

fun NodeStyle.Companion.hierarchical(parent: NodeStyle?=null)=HierarchicalNodeStyle(parent)

 class HierarchicalNodeStyle(
     var parent: NodeStyle?
): NodeStyle {

    private val style: NodeStyle = NodeStyleImpl()

    private var fillSet = false

    override var fill: ColorOrBrush?
        get() = if (fillSet) style.fill else parent?.fill
        set(value) {
            fillSet = true
            style.fill = value
        }

    private var dashedLineSet = false

    override var dashedLine: DoubleArray?
        get() =
            if (dashedLineSet)
                style.dashedLine
            else
                parent?.dashedLine

        set(value) {
            dashedLineSet = true
            style.dashedLine = value
        }

    private var strokeSet = false

    override var strokeColor: ColorOrBrush?
        get() = if (strokeSet) style.strokeColor else parent?.strokeColor
        set(value) {
            strokeSet = true
            style.strokeColor = value
        }

    private var strokeWidthSet = false
    override var strokeWidth: Float?
        get() = if (strokeWidthSet) style.strokeWidth else parent?.strokeWidth
        set(value) {
            strokeWidthSet = true
            style.strokeWidth = value
        }

    private var textColorSet = false
    override var textColor: ColorOrBrush?
        get() = if (textColorSet) style.textColor else parent?.textColor
        set(value) {
            textColorSet = true
            style.textColor = value
        }


    private var hAlignSet = false
    override var hAlign: TextHAlign
        get() = if (hAlignSet) style.hAlign else parent?.hAlign!!
        set(value) {
            hAlignSet = true
            style.hAlign = value
        }


    private var vAlignSet = false
    override var vAlign: TextVAlign
        get() = if (vAlignSet) style.vAlign else parent?.vAlign!!
        set(value) {
            vAlignSet = true
            style.vAlign = value
        }
}


fun NodeStyle.toDrawStyle(default: DrawStyle = Fill ):DrawStyle{
    if( fill != null ) return default

   return strokeWidth.ifNullValue(default,Stroke(strokeWidth!!))
}

fun NodeStyle.getColorOrGradient():ColorOrBrush?{
    return fill?:strokeColor
}